home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Gekkan Dennou Club 147
/
Gekkan Dennou Club - 2000.8 Vol. 147 (Japan).7z
/
Gekkan Dennou Club - 2000.8 Vol. 147 (Japan) (Track 1).bin
/
tools
/
zmc3v078
/
zmc3v078.lzh
/
SRCSV078.LZH
/
VELO.C
< prev
next >
Wrap
C/C++ Source or Header
|
2000-02-24
|
11KB
|
487 lines
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "parsesub.h"
#include "etc.h"
#include "structs.h"
#include "structs2.h"
UBYTE *getSpecialVelocity(UBYTE *zms,VELOETCVAR *v);
WORD setVelo0(TRKCHINF *trkdata, const int Trk,VELOETCVAR v,BYTE *relvelo,TRKINF *trkinf,
COMMONINF *cominf,UWORD step);
int setVelo(TRKCHINF *trkdata, const int Trk,TRKINF *trkinf,COMMONINF *cominf,
UWORD step, WORD *v);
void vSeqLoopChk(const int Trk,TRKINF *trkinf);
UBYTE *setMMLatU(UBYTE *zms,TRKCHINF *trkdata,TRKINF *trkinf,
const BYTE target[], int mode);
inline DWORD rand2(DWORD r);
UBYTE *makeZmdRandVelo(UBYTE *zms,TRKCHINF *trkdata, const int Trk,
TRKINF *trkinf,COMMONINF *cominf,
int line,char *linebuf);
int setVeloRevise(TRKINF *trkinf, const int Trk,COMMONINF *cominf,UWORD step);
UBYTE *dispatchVelo(UBYTE *zms, TRKCHINF *trkdata, TRKINF *trkinf,
COMMONINF *cominf,const BYTE target[]);
UBYTE *makeVeloOffset(UBYTE *zms,TRKINF *trkinf, const BYTE target[]);
extern DWORD line;
extern char *linebuf;
extern LINEDATA *ld;
UBYTE *dispatchVelo(UBYTE *zms, TRKCHINF *trkdata, TRKINF *trkinf,
COMMONINF *cominf,const BYTE target[])
{
DWORD line_ = line;
const LINEDATA *ld_ = ld;
char *linebuf_ = linebuf;
const char *comtbl[] = {
"level","depth","deepen","control","origin",
"reset","speed","delay","waveform","switch",
"sync","mode","phase","offset","revise",
NULL
};
zms = skipSpc(zms);
if (*zms != '.') { /* [velocity] */
zms = setMMLatU(zms, trkdata, trkinf, target, 0);
} else {
DWORD tmpDWORD;
int i,trk,err;
zms++;
for (i = 0;;i++) {
if (!comtbl[i]) {
i = -1;
break;
} else if (!stricmp2(zms,comtbl[i])) {
zms += strlen(comtbl[i]);
break;
}
}
switch (i) {
case 13: /* [VELOCITY.offset */
zms = makeVeloOffset(zms,trkinf,target);
case 14: /* [VELOCITY.revise] */
for (trk = 0; target[trk] >= 0; trk++) {
zms = makeZmdRandVelo(zms,trkdata,target[trk],
trkinf,cominf,line,linebuf);
}
zmserror("[velocity.revise] can use only for zmc2/zmc3.",line,linebuf,zms,4,1);
break;
default:
break;
}
}
return zms;
}
UBYTE *makeVeloOffset(UBYTE *zms,TRKINF *trkinf, const BYTE target[])
{
/* const char *p[] = {"on", "off", NULL};*/
DWORD mode, offset;
int err, trk;
/* zms = getnum4(zms, &mode, &err, p, 0);*/
zms = getnum2(zms, &offset, &err);
if (!err < 0) {
zmserror("[VELOCITY.OFFSET] format error.",line,linebuf,zms,0,1);
}
for (trk = 0; target[trk] >= 0; trk++) {
const int Trk = target[trk];
trkinf[Trk].veloofst = offset;
}
return zms;
}
/* ===============================================
get Special Velocity from MML, if there is.
=============================================== */
UBYTE *getSpecialVelocity(UBYTE *zms,VELOETCVAR *v)
{
/* v->relflg[0] = 2; */ /* 0:abs 1:rel 2:omit -1:guardian */
/* del v0.74 */
if (*zms == ',') {
DWORD velo;
int err;
zms = skipSpcCr(++zms);
if (*zms == '+' || *zms == '-') {
v->relflg[0] = 1;
/*
} else if (*zms == '-') {
v->relflg[0] = -1;
*/
}
zms = getnum2(zms, &velo, &err);
if (err < 0) { /* no value */
/* put error */
} else {
if (v->relflg[0] == 2) {
v->relflg[0] = 0;
}
/*
if (v->relflg[0] < 0) {
v->relflg[0] = 1;
v->var[0] = -velo;
} else {
*/
v->var[0] = velo;
/* fprintf(stderr,"(%d/%d)",v->var[0],v->relflg[0]); */
/*
}
*/
}
}
return zms;
}
/* set special velocity */
/* relvelo: 0; default
* 1; relative value
* -1; absolute value
*/
WORD setVelo0(TRKCHINF *trkdata, const int Trk,VELOETCVAR v,BYTE *relvelo,TRKINF *trkinf,
COMMONINF *cominf,UWORD step)
{
/* const int Trk = target[trk]; */
WORD retvelo = -1;
*relvelo = 0; /* use default */
/* zms = getSpecialVelocity(zms,v); */
if (v.relflg[0] != 2) { /* special velocity is there */
BYTE *vpos = &(trkinf[Trk].velozpos); /* calc random parameter */
const WORD rvar = trkinf[Trk].velocity[*vpos].var[1];
const DWORD r = trkinf[Trk].velou.var[1];
WORD vrvar = 0;
if ( trkinf[Trk].velocity[*vpos].var[1] ) { /* random? */
vrvar = rvar;
} else if (r) {
vrvar = r;
}
if (vrvar) {
vrvar = rand2(vrvar);
}
*relvelo = -1;
if (v.relflg[0] == 1) {
/*
if (v.var[0] >= 0) {
*trkdata[Trk].zmd++ = 0xDA;
*trkdata[Trk].zmd++ = v.var[0] + vrvar;
*/
retvelo = v.var[0] + vrvar;
/*
} else {
*trkdata[Trk].zmd++ = 0xDB;
*trkdata[Trk].zmd++ = -v.var[0] + vrvar;
retvelo = -v.var[0] + vrvar;
}
*/
*relvelo = 1;
} else {
/*
*trkdata[Trk].zmd++ = 0xD9;
*trkdata[Trk].zmd++ = v.var[0] + vrvar;
*/
retvelo = v.var[0] + vrvar;
*relvelo = -1;
}
/* printf("[vv=%d]",v->var); */
trkinf[Trk].spvelomode = 1;
} else { /* special velocity is not there */
WORD v = retvelo;
int rv = setVelo(trkdata,Trk,trkinf,cominf,step,&v);
if (rv) {
trkinf[Trk].spvelomode = 1;
*relvelo = rv;
}
retvelo = v;
}
/* del 0.74 */
/*
if (trkinf[Trk].veloseqsw) {
vSeqLoopChk(Trk,trkinf);
}
*/
return retvelo;
}
/* =======================
set normal velocity
(velocity sequence)
return 1, if random pattern(special velocity) is used.
return 0, if no velocity sequence. *v isn't modified.
======================= */
int setVelo(TRKCHINF *trkdata, const int Trk,TRKINF *trkinf,COMMONINF *cominf,
UWORD step,WORD *v)
{
BYTE *vpos = &(trkinf[Trk].velozpos);
WORD vvar = 0;
const WORD rvar = trkinf[Trk].velocity[*vpos].var[1];
/* const BYTE vnum = trkinf[Trk].veloznum; */
const DWORD r = trkinf[Trk].velou.var[1];
int ret = 0;
recoverSpecialVelocity(trkinf, Trk);
/*
if ( trkinf[Trk].veloz[1].relflg[0] && trkinf[Trk].veloseqsw) {
*/
if ( trkinf[Trk].velou.relflg[0] && trkinf[Trk].veloseqsw) {
/* Z velocity */
/* veloz[1].relflg[0] is set
* by setVelocitySequenceMode */
int v = trkinf[Trk].velocity[*vpos].var[0] + trkinf[Trk].veloofst;
if (v > 127) {
v = 127;
} else if (v < 0) {
v = 0;
}
if (trkinf[Trk].velocity[*vpos].var[0] != 0x80 || rvar) {
*trkdata[Trk].zmd++ = 0x93;
*trkdata[Trk].zmd++ = v;
}
ret = 0; /* don't set '-1' */
vvar = v;
if ( rvar ) { /* random? */
/* printf("#%d",trkinf[Trk].veloz[*vpos].var[1]); */
/* vvar += rand2(rvar); */
vvar = rand2(rvar); /* v0.72 */
ret = 1;
}
/* *velo = vvar; */
} else if (r) { /* random parameter */
vvar = rand2(r);
ret = 1;
}
if (trkinf[Trk].randvelopower) {
vvar += -setVeloRevise(trkinf,Trk,cominf,step);
ret = 1;
}
if (ret) {
/*
*trkdata[Trk].zmd++ = (vvar >= 0)? 0xDA : 0xDB;
*trkdata[Trk].zmd++ = (vvar >= 0)? vvar : -vvar;
*/
/* *v += vvar; */
*v = vvar;
}
/* vSeqLoopChk(Trk,trkinf); */
return ret;
}
void vSeqLoopChk(const int Trk,TRKINF *trkinf)
{
/* BYTE *vpos = &(trkinf[Trk].velozpos); */
const BYTE vnum = trkinf[Trk].veloznum;
/* if (vnum > 0) { */
if (trkinf[Trk].velou.relflg[0]) {
if (++(trkinf[Trk].velozpos) >= vnum) {
trkinf[Trk].velozpos = 0;
}
}
}
/*tenuki*/
UBYTE *setMMLatU(UBYTE *zms,TRKCHINF *trkdata,TRKINF *trkinf,
const BYTE target[], int mode)
{ /* mode=0:@U mode=1: [@VELOCITY]
* mml 'u' doesn't support
*/
UBYTE *zms_ = zms;
int trk;
for (trk = 0; target[trk] >= 0; trk++) {
const int Trk = target[trk];
BYTE rel = 0;
DWORD velo,v = trkinf[Trk].velou.var[0];
DWORD r = trkinf[Trk].velou.var[1];
DWORD rp = (r)? rand2(r) : 0;
int err;
/* line = line_; */
/* ld = ld_; */
zms = skipSpcCr(zms_);
if (*zms == '+') {
rel = 1;
} else if (*zms == '-') {
rel = -1;
}
zms = getnum2(zms, &velo, &err);
zms = skipSpcCr(zms);
if (*zms == ':' && *(zms + 1) != '|') {
int err2;
zms = skipSpcCr(zms + 1);
zms = getnum2(zms, &r, &err2);
r = abs(r);
rp = (r && !err2)? rand2(r) : 0;
trkinf[Trk].velou.var[1] = r;
}
if (err < 0) { /* only '@u' */
if (trkinf[Trk].relvelo != 0) { /*relational value */
v += trkinf[Trk].relvelo;
} else { /* absolute value */
v = trkinf[Trk].velou.var[0];
}
} else {
if (rel || mode > 0) {
v += velo;
trkinf[Trk].relvelo = velo;
} else {
v = velo;
trkinf[Trk].relvelo = 0;
}
v += rp;
if (v > 127) {
v = 127;
} else if (v < 0) {
v = 0;
}
trkinf[Trk].velou.var[0] = v;
}
if (!mode) {
v += trkinf[Trk].veloofst;
if (v > 127) {
v = 127;
} else if (v < 0) {
v = 0;
}
*trkdata[Trk].zmd++ = 0x93;
*trkdata[Trk].zmd++ = v;
} else {
*trkdata[Trk].zmd++ = 0x94;
*trkdata[Trk].zmd++ = velo;
}
/* trkinf[Trk].veloznum = 0; */
/* trkinf[Trk].veloz[1].relflg[0] = 0; */
setVelocitySequenceMode(trkinf,Trk,0);
}
return zms;
}
/* ===================================
get random number: -r <= x <= r
=================================== */
inline DWORD rand2(DWORD r)
{
return (rand() % (r * 2 + 1)) - r;
}
UBYTE *makeZmdRandVelo(UBYTE *zms,TRKCHINF *trkdata, const int Trk,
TRKINF *trkinf,COMMONINF *cominf,
int line,char *linebuf)
{
DWORD randvelotype,randvelopower;
int err;
zms = skipSpc(zms);
zms = getnum2(zms,&randvelotype,&err);
trkinf[Trk].randvelotype = (err)? 0 : randvelotype;
zms = skipSpc(zms);
if (*zms != ',') {
if (*zms != ']') {
zmserror("SYNTAX ERROR.",line,linebuf,zms,0,1);
} else {
return zms;
}
}
zms = skipSpc(zms + 1);
zms = getnum2(zms,&randvelopower,&err);
trkinf[Trk].randvelopower = (err)? 0 : randvelopower;
zms = skipSpc(zms);
if (*zms != ']') {
zmserror("SYNTAX ERROR.",line,linebuf,zms,0,1);
}
return zms + 1; /* skip ] */
}
/* ========================
returns revise value
======================== */
int setVeloRevise(TRKINF *trkinf, const int Trk,COMMONINF *cominf,UWORD step)
{
/*
| [VELOCITY.REVISE type,power] とすると、「音長が短くなれば
| なるほどマイナス方向にベロシティをランダム補正する」ように
| なる。powerが補正の強さ(0で補正オフ)、typeが補正曲線指定
| (0=log曲線補正 1=線形補正1 2=線形補正2 ...)。
| デフォルトでは補正オフ。
*/
int ret = 0;
const int randvelotype = trkinf[Trk].randvelotype;
switch(randvelotype) {
case 16:
case 24:
if (trkinf[Trk].laststep >= step * 2) {
break;
}
/* NO BREAK */
case 0: /* log */
case 8:
do {
int div1,div2,temp;
for (div1 = 0, temp = cominf->div; temp; div1++, temp /= 2) {
}
for (div2 = 0, temp = step; temp; div2++, temp /= 2) {
}
if ((randvelotype / 8) & 1) {
div1 -= 2;
}
ret = trkinf[Trk].randvelopower * (div1 - div2);
} while (0);
break;
case 1: /* linear1 */
ret = trkinf[Trk].randvelopower * (cominf->div / step);
break;
case 2: /* linear2 */
ret = (cominf->div / step) / trkinf[Trk].randvelopower;
break;
default:
return 0;
}
trkinf[Trk].laststep = step;
return ret;
}